import threading
import time

from serial.serialwin32 import Serial

from src.utils.crc_util import CRCUtil


class LwSerialConnector:
    """
    modbus serrial connector class
    """
    _instance = None
    _instance_lock = threading.Lock()

    def __init__(self):
        self.serial_client: Serial = None

    @classmethod
    def get_instance(cls):
        if not cls._instance:
            with cls._instance_lock:
                if not cls._instance:
                    cls._instance = LwSerialConnector()
        return cls._instance

    def modbus_serial_client(self):
        if self.serial_client is None:
            try:
                self.serial_client = Serial(port="COM3", baudrate=19200, timeout=1)
                print(f"serial client status: {self.serial_client.is_open}")
            except Exception as e:
                print(f"Failed to connect to modbus serial port: {e}")
        else:
            print(f"Modbus serial client already connected")

    def send_modbus_rtu(self, cmd: str):
        # 计算crc
        crc_hex_str = CRCUtil.crc_16(cmd)
        cmd_str = cmd + crc_hex_str
        # 发送命令
        self.serial_client.write(cmd_str.encode())
        # 等待响应
        time.sleep(0.1)
        res = self.serial_client.read(len(cmd_str))
        print(f"modbus rtu command response: {res}")
        return res

    def read_bytes(self):
        self.serial_client.read()

    def read_driver_register(self):
        """
        读取驱动器寄存器
        03H
        :return:
        """
        self.serial_client.read_all()


if __name__ == "__main__":
    serial_connector = LwSerialConnector.get_instance()
    serial_connector.modbus_serial_client()
    # cmd_str = "010302020002"
    # cmd_str = "010302000001"
    cmd_str = "01030C020001"
    # # 计算crc
    # crc_hex_str = CRCUtil.crc_16(cmd_str)
    # cmd = cmd_str + crc_hex_str
    # print(f"cmd: {cmd}")
    # res_bytes = serial_connector.serial_client.read_all()
    # print(f"{res_bytes}")
    serial_connector.send_modbus_rtu(cmd_str)
